﻿using System;
using nRoute.Components;
using nRoute.Components.Composition;
using nRoute.Components.Disposer;
using nRoute.Samples.OfficerXcel.Services;
using nRoute.SiteMaps;
using nRoute.ViewModels;
using System.Collections.Generic;
using nRoute.Components.Handlers;
using System.ComponentModel;

namespace nRoute.Samples.OfficerXcel.ViewModels
{
    [MapViewModel(typeof(Shell))]
    public class ShellViewModel
        : ViewModelBase
    {
        private const string DEFAULT_TITLE = "Office(r) Xcel";
        private const string TITLE_FORMAT = "Office(r) Xcel - {0}{1}";
        private const string ISDIRTY_INDICATOR = " *";

        private readonly IActiveWorksheetService _activeWorksheetService;
        private Handler<PropertyChangedEventArgs, PropertyChangedEventHandler> _propertyChangedHandler;
        private bool _isDirty;
        private string _title;
        
        [ResolveConstructor]
        public ShellViewModel(IActiveWorksheetService activeWorksheetService)
        {
            if (activeWorksheetService == null) throw new ArgumentNullException("activeWorksheetService");
            _activeWorksheetService = activeWorksheetService;

            SetupCommads();
            SetupActiveWorksheetListeners();
            _activeWorksheetService.ActiveWorksheetChanged += (s, e) => SetupActiveWorksheetListeners();
        
            SiteMapService.LoadSiteMap((s) =>
            {
                if (s != null)
                {
                   SiteMapNodes = s.RootNode.ChildNodes;
                   NotifyPropertyChanged(() => SiteMapNodes);
                }
            });
        }

#region Properties

        public ActionCommand ShowWorksheetReverseCommand { get; private set; }

        public IEnumerable<SiteMapNode> SiteMapNodes { get; private set; }

        public bool IsDirty
        {
            get { return _isDirty; }
            private set
            {
                if (_isDirty != value)
                {
                    _isDirty = value;
                    NotifyPropertyChanged(() => IsDirty);
                    NotifyPropertyChanged(() => Title);
                }
            }
        }

        public string Title
        {
            get { return _title; }
            private set
            {
                if (!string.Equals(_title, value, StringComparison.InvariantCulture))
                {
                    _title = value;
                    NotifyPropertyChanged(() => Title);
                }
            }
        }

#endregion

#region Helpers

        private void SetupCommads()
        {
            ShowWorksheetReverseCommand = new ActionCommand(() => { });
        }

        private void SetupActiveWorksheetListeners()
        {
            if (_propertyChangedHandler != null) _propertyChangedHandler.Dispose();

            if (_activeWorksheetService.ActiveWorksheet == null)
            {
                Title = DEFAULT_TITLE;
                IsDirty = false;
            }
            else
            {
                var _worksheet = _activeWorksheetService.ActiveWorksheet;
                Title = FormatTitle(_worksheet.Title);
                IsDirty = _worksheet.IsDirty;

                _propertyChangedHandler = new Handler<PropertyChangedEventArgs, PropertyChangedEventHandler>((s, e) =>
                {
                    Title = FormatTitle(_worksheet.Title);
                    IsDirty = _worksheet.IsDirty;
                },
                (h) => _worksheet.PropertyChanged -= h).DisposeWith(_worksheet.Disposer);
                _worksheet.PropertyChanged += _propertyChangedHandler;

                ShowWorksheetReverseCommand.Execute();
            }
        }

        private string FormatTitle(string title)
        {
            return string.IsNullOrEmpty(title) ? DEFAULT_TITLE : 
                string.Format(TITLE_FORMAT, title, IsDirty ? ISDIRTY_INDICATOR : string.Empty);
        }

#endregion

    }
}
